/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright 2014-2016 Freescale Semiconductor, Inc.
 * Copyright 2017,2019-2020 NXP
 *
 */
#ifndef _FSL_S32V234_CPU_H
#define _FSL_S32V234_CPU_H

#include <config.h>

#ifndef CONFIG_SYS_DCACHE_OFF
#define SECTION_SHIFT_L0	39UL
#define SECTION_SHIFT_L1	30UL
#define SECTION_SHIFT_L2	21UL
#define BLOCK_SIZE_L0	BIT_ULL(SECTION_SHIFT_L0)
#define BLOCK_SIZE_L1	BIT(SECTION_SHIFT_L1)
#define BLOCK_SIZE_L2	BIT(SECTION_SHIFT_L2)
#define NUM_OF_ENTRY            512
#define TCR_EL2_PS_40BIT	(2 << 16)
#define S32V_VA_BITS		(40)
#define S32V_TCR	(TCR_TG0_4K		| \
			TCR_EL2_PS_40BIT	| \
			TCR_SHARED_NON		| \
			TCR_ORGN_NC		| \
			TCR_IRGN_NC		| \
			TCR_T0SZ(S32V_VA_BITS))
#define S32V_TCR_FINAL (TCR_TG0_4K		| \
			TCR_EL2_PS_40BIT	| \
			TCR_SHARED_OUTER	| \
			TCR_ORGN_WBWA		| \
			TCR_IRGN_WBWA		| \
			TCR_T0SZ(S32V_VA_BITS))

#define CONFIG_SYS_FSL_IRAM_BASE        (IRAM_BASE_ADDR)

#define CONFIG_SYS_FSL_IRAM_SIZE        (0x800000)

#define CONFIG_SYS_FSL_PERIPH_BASE      0x40000000

#define CONFIG_SYS_FSL_PERIPH_SIZE      0x40000000

struct sys_mmu_table {
	u64 virt_addr;
	u64 phys_addr;
	u64 size;
	u64 memory_type;
	u64 share;
};

struct table_info {
	u64 *ptr;
	u64 table_base;
	u64 entry_size;
};

static const struct sys_mmu_table s32_early_mmu_table[] = {
	/* DRAM_SIZE1 is configurable via defconfig, but there are both
	 * address and size alignment restrictions in the MMU table lookup code
	 */
	{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
	  ALIGN(CONFIG_SYS_FSL_DRAM_SIZE1, BLOCK_SIZE_L1), MT_NORMAL_NC,
	  PTE_BLOCK_OUTER_SHARE },
	{ CONFIG_SYS_FSL_IRAM_BASE, CONFIG_SYS_FSL_IRAM_BASE,
	  CONFIG_SYS_FSL_IRAM_SIZE, MT_NORMAL_NC, PTE_BLOCK_OUTER_SHARE },
	{ CONFIG_SYS_FSL_PERIPH_BASE, CONFIG_SYS_FSL_PERIPH_BASE,
	  CONFIG_SYS_FSL_PERIPH_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
	{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
	  CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL_NC, PTE_BLOCK_OUTER_SHARE },
	{ CONFIG_SYS_FSL_FLASH0_BASE, CONFIG_SYS_FSL_FLASH0_BASE,
	  CONFIG_SYS_FSL_FLASH0_SIZE, MT_NORMAL_NC, PTE_BLOCK_OUTER_SHARE },
#ifdef CONFIG_SYS_FSL_FLASH1_BASE
	{ CONFIG_SYS_FSL_FLASH1_BASE, CONFIG_SYS_FSL_FLASH1_BASE,
	  CONFIG_SYS_FSL_FLASH1_SIZE, MT_NORMAL_NC, PTE_BLOCK_OUTER_SHARE },
#endif
};

static const struct sys_mmu_table s32_final_mmu_table[] = {
	{ CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1,
	  ALIGN(CONFIG_SYS_FSL_DRAM_SIZE1, BLOCK_SIZE_L1), MT_NORMAL_NC,
	  PTE_BLOCK_OUTER_SHARE },
	{ CONFIG_SYS_FSL_IRAM_BASE, CONFIG_SYS_FSL_IRAM_BASE,
	  CONFIG_SYS_FSL_IRAM_SIZE, MT_NORMAL, PTE_BLOCK_OUTER_SHARE },
	{ CONFIG_SYS_FSL_PERIPH_BASE, CONFIG_SYS_FSL_PERIPH_BASE,
	  CONFIG_SYS_FSL_PERIPH_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE },
	{ CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2,
	  CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, PTE_BLOCK_OUTER_SHARE },
	{ CONFIG_SYS_FSL_FLASH0_BASE, CONFIG_SYS_FSL_FLASH0_BASE,
	  CONFIG_SYS_FSL_FLASH0_SIZE, MT_NORMAL, PTE_BLOCK_OUTER_SHARE },
#ifdef CONFIG_SYS_FSL_FLASH1_BASE
	{ CONFIG_SYS_FSL_FLASH1_BASE, CONFIG_SYS_FSL_FLASH1_BASE,
	  CONFIG_SYS_FSL_FLASH1_SIZE, MT_NORMAL, PTE_BLOCK_OUTER_SHARE },
#endif
};

#endif

u32 cpu_mask(void);
int cpu_numcores(void);

#endif /* _FSL_S32V234_CPU_H */
